package linked_list;


public class LinkedList<E> implements List<E> {
    transient int size = 0;
    /**
     * 链表头节点
     */
    transient Node<E> first;
    /**
     * 链表尾节点
     */
    transient Node<E> last;

    /**
     * 在头节点前面插入元素
     *
     * @param e 要插入的元素
     */
    void linkFirst(E e) {
        // 1. 先将头节点记录下来
        final Node<E> f = first;
        // 2. 新创建一个节点，指定 next 节点为之前的头节点，
        final Node<E> newNode = new Node<>(null, e, f);
        // 3. 指定新的头节点为新节点
        first = newNode;
        // 4. 如果链表为空，则 first 和 last 都是新增的节点
        if (f == null) {
            last = newNode;
        } else {
            f.prev = newNode;
        }
        size++;
    }

    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null) {
            // 链表中没有元素
            first = newNode;
        } else {
            l.next = newNode;
        }
        size++;
    }

    /**
     * 拆链操作，给定一个元素，它就可以把当前这个元素的上一个节点和下一个节点进行相连，之后把自己删除
     * 这个方法常用于 remove 移除元素操作，因为整个操作过程不需要遍历，所以时间复杂度为 O(1)
     *
     * @param x
     * @return
     */
    E unlink(Node<E> x) {
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;
        if (prev == null) {
            // 上一个节点是头节点
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }
        if (next == null) {
            // 当前节点是尾节点，将当前元素的上一个节点设置为链表的尾节点
            last = prev;
        } else {
            // 当前节点不是尾节点，将当前节点的 next 节点的 prev 节点设置为 当前节点的 prev 节点
            next.prev = prev;
            x.next = null;
        }
        x.item = null;
        size--;
        return element;
    }

    @Override
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    @Override
    public boolean addFirst(E e) {
        linkFirst(e);
        return true;
    }

    @Override
    public boolean addLast(E e) {
        linkLast(e);
        return true;
    }

    @Override
    public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public E get(int index) {
        return null;
    }

    Node<E> node(int index) {
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++) {
                x = x.next;
            }
            return x;
        } else {
            Node<E> x = last;
            for (int i = size-1; i >index; i--) {
                x = x.prev;
            }
            return x;
        }
    }
    @Override
    public void printLinkList() {
        if (size == 0) {
            System.out.println(" 链表为空！ ");
        } else {
            Node<E> temp = first;
            System.out.print("目前的列表，头节点：" + first.item + " 尾节点：" + last.item + " 整体：");
            while (temp != null) {
                System.out.print(temp.item+",");
                temp = temp.next;
            }
            System.out.println();
        }
    }

    /**
     * ? 表示不确定的 Java 类型
     * T (type) 表示具体的一个 Java 类型
     *
     * @param <E>
     */
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        public Node(Node<E> prev, E item, Node<E> next) {
            this.item = item;
            this.next = next;
            this.prev = prev;
        }
    }
}
